<!--
  3D Model Demo Component

  This demo shows how to load and manipulate 3D models in CesiumJS.
  It demonstrates different model formats, positioning, scaling, and animation.

  Features:
    - Loading glTF models
    - Model positioning and orientation
    - Model scaling
    - Model color styling
    - Model animations
-->

<template>
  <div class="demo-container">
    <BaseCesiumViewer 
      ref="cesiumViewer" 
      
      @viewer-ready="onViewerReady"
    />
    <div class="control-panel">
      <h3>Model Controls</h3>
      
      <div class="control-group">
        <h4>Model Selection</h4>
        <ControlItem
          type="select"
          label="Active Model"
          :value="selectedModel"
          @update:value="selectedModel = $event"
        >
          <option value="model1">Cesium Air (Default)</option>
          <option value="model2">Cesium Air (Colored)</option>
          <option value="model3">Cesium Air (Scaled)</option>
        </ControlItem>
      </div>
      
      <div class="control-group">
        <h4>Model Properties</h4>
        <ControlItem
          type="range"
          label="Scale"
          :value="modelSettings.scale"
          :min="0.1"
          :max="5"
          :step="0.1"
          @update:value="modelSettings.scale = $event"
          @input="updateModelProperties"
        />
        
        <ControlItem
          type="range"
          label="Minimum Pixel Size"
          :value="modelSettings.minimumPixelSize"
          :min="1"
          :max="256"
          :step="1"
          @update:value="modelSettings.minimumPixelSize = $event"
          @input="updateModelProperties"
        />
        
        <ControlItem
          type="range"
          label="Maximum Scale"
          :value="modelSettings.maximumScale"
          :min="1000"
          :max="100000"
          :step="1000"
          @update:value="modelSettings.maximumScale = $event"
          @input="updateModelProperties"
        />
      </div>
      
      <div class="control-group">
        <h4>Color Settings</h4>
        <ControlItem
          type="checkbox"
          label="Enable Color Tint"
          :value="modelSettings.colorEnabled"
          label-after
          @update:value="modelSettings.colorEnabled = $event"
          @change="updateModelProperties"
        />
        
        <ControlItem
          v-if="modelSettings.colorEnabled"
          type="range"
          label="Red: {{ Math.round(modelSettings.color.red * 255) }}"
          :value="modelSettings.color.red"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="modelSettings.color.red = $event"
          @input="updateModelProperties"
        />
        
        <ControlItem
          v-if="modelSettings.colorEnabled"
          type="range"
          label="Green: {{ Math.round(modelSettings.color.green * 255) }}"
          :value="modelSettings.color.green"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="modelSettings.color.green = $event"
          @input="updateModelProperties"
        />
        
        <ControlItem
          v-if="modelSettings.colorEnabled"
          type="range"
          label="Blue: {{ Math.round(modelSettings.color.blue * 255) }}"
          :value="modelSettings.color.blue"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="modelSettings.color.blue = $event"
          @input="updateModelProperties"
        />
        
        <ControlItem
          v-if="modelSettings.colorEnabled"
          type="range"
          label="Alpha: {{ Math.round(modelSettings.color.alpha * 255) }}"
          :value="modelSettings.color.alpha"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="modelSettings.color.alpha = $event"
          @input="updateModelProperties"
        />
      </div>
      
      <div class="control-group">
        <h4>Color Blend</h4>
        <ControlItem
          type="select"
          label="Blend Mode"
          :value="modelSettings.colorBlendMode"
          @update:value="modelSettings.colorBlendMode = $event"
          @change="updateModelProperties"
        >
          <option value="NONE">None</option>
          <option value="HIGHLIGHT">Highlight</option>
          <option value="REPLACE">Replace</option>
          <option value="MIX">Mix</option>
        </ControlItem>
        
        <ControlItem
          v-if="modelSettings.colorBlendMode === 'MIX'"
          type="range"
          label="Blend Amount"
          :value="modelSettings.colorBlendAmount"
          :min="0"
          :max="1"
          :step="0.01"
          @update:value="modelSettings.colorBlendAmount = $event"
          @input="updateModelProperties"
        />
      </div>
      
      <button @click="resetToDefaults" class="reset-button">Reset to Defaults</button>
    </div>
  </div>
</template>

<script>
import { ref, reactive } from 'vue';
import BaseCesiumViewer from '../core/BaseCesiumViewer.vue';
import ControlItem from '../components/ControlItem.vue';
import { setViewPosition } from '../utils';

export default {
  name: 'ModelDemo',
  components: {
    BaseCesiumViewer,
    ControlItem
  },
  setup() {
    // References to Cesium entities
    let model1, model2, model3, viewer, Cesium;
    
    // Reactive settings for UI controls
    const selectedModel = ref('model1');
    const modelSettings = reactive({
      scale: 1.0,
      minimumPixelSize: 64,
      maximumScale: 20000,
      colorEnabled: false,
      color: {
        red: 1.0,
        green: 1.0,
        blue: 1.0,
        alpha: 1.0
      },
      colorBlendMode: 'NONE',
      colorBlendAmount: 0.5
    });

    const onViewerReady = async (payload) => {
      // Check if payload and viewer are valid
      if (!payload || !payload.viewer) {
        console.error('Viewer is not ready or payload is invalid');
        return;
      }
      
      viewer = payload.viewer;
      Cesium = payload.Cesium;
      
      try {
        // Set initial view
        setViewPosition(viewer, {
          lon: -75.5972,
          lat: 40.0385,
          height: 5000
        });

        // Load a sample model (Cesium Air)
        const position = Cesium.Cartesian3.fromDegrees(-75.5972, 40.0385, 1000.0);
        const heading = Cesium.Math.toRadians(135);
        const pitch = 0;
        const roll = 0;
        const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
        const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

        model1 = viewer.entities.add({
          name: 'Cesium Air',
          position: position,
          orientation: orientation,
          model: {
            uri: '/assets/models/CesiumAir.glb',
            minimumPixelSize: 128,
            maximumScale: 20000
          }
        });

        // Create a second model with different properties
        const position2 = Cesium.Cartesian3.fromDegrees(-75.6022, 40.0435, 1000.0);
        const heading2 = Cesium.Math.toRadians(45);
        const hpr2 = new Cesium.HeadingPitchRoll(heading2, 0, 0);
        const orientation2 = Cesium.Transforms.headingPitchRollQuaternion(position2, hpr2);

        model2 = viewer.entities.add({
          name: 'Colored Cesium Air',
          position: position2,
          orientation: orientation2,
          model: {
            uri: '/assets/models/CesiumAir.glb',
            minimumPixelSize: 64,
            maximumScale: 10000,
            color: Cesium.Color.fromBytes(255, 0, 0, 200), // Semi-transparent red
            colorBlendMode: Cesium.ColorBlendMode.MIX,
            colorBlendAmount: 0.5
          }
        });

        // Create a third model with scale
        const position3 = Cesium.Cartesian3.fromDegrees(-75.5922, 40.0335, 1000.0);
        const heading3 = Cesium.Math.toRadians(270);
        const hpr3 = new Cesium.HeadingPitchRoll(heading3, 0, 0);
        const orientation3 = Cesium.Transforms.headingPitchRollQuaternion(position3, hpr3);

        model3 = viewer.entities.add({
          name: 'Scaled Cesium Air',
          position: position3,
          orientation: orientation3,
          model: {
            uri: '/assets/models/CesiumAir.glb',
            scale: 2.0,
            minimumPixelSize: 32,
            maximumScale: 50000
          }
        });

        // Fly to the models
        viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-20), 5000));

        // Add a ground plane for reference
        viewer.entities.add({
          name: 'Ground reference',
          polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
              -75.6072, 40.0285,
              -75.5872, 40.0285,
              -75.5872, 40.0485,
              -75.6072, 40.0485
            ]),
            material: Cesium.Color.GRAY.withAlpha(0.3)
          }
        });

        console.log('Models loaded successfully');
      } catch (error) {
        console.error('Error loading models:', error);
      }
    };
    
    // Get the currently selected model entity
    const getSelectedModel = () => {
      switch (selectedModel.value) {
        case 'model1': return model1;
        case 'model2': return model2;
        case 'model3': return model3;
        default: return model1;
      }
    };
    
    // Update model properties based on UI controls
    const updateModelProperties = () => {
      const model = getSelectedModel();
      if (!model || !model.model) return;
      
      // Update scale properties
      model.model.scale = modelSettings.scale;
      model.model.minimumPixelSize = modelSettings.minimumPixelSize;
      model.model.maximumScale = modelSettings.maximumScale;
      
      // Update color properties
      if (modelSettings.colorEnabled) {
        model.model.color = new Cesium.Color(
          modelSettings.color.red,
          modelSettings.color.green,
          modelSettings.color.blue,
          modelSettings.color.alpha
        );
      } else {
        model.model.color = undefined;
      }
      
      // Update blend mode
      switch (modelSettings.colorBlendMode) {
        case 'NONE':
          model.model.colorBlendMode = Cesium.ColorBlendMode.NONE;
          break;
        case 'HIGHLIGHT':
          model.model.colorBlendMode = Cesium.ColorBlendMode.HIGHLIGHT;
          break;
        case 'REPLACE':
          model.model.colorBlendMode = Cesium.ColorBlendMode.REPLACE;
          break;
        case 'MIX':
          model.model.colorBlendMode = Cesium.ColorBlendMode.MIX;
          break;
      }
      
      model.model.colorBlendAmount = modelSettings.colorBlendAmount;
    };
    
    // Reset to defaults based on the selected model
    const resetToDefaults = () => {
      switch (selectedModel.value) {
        case 'model1':
          modelSettings.scale = 1.0;
          modelSettings.minimumPixelSize = 128;
          modelSettings.maximumScale = 20000;
          modelSettings.colorEnabled = false;
          modelSettings.colorBlendMode = 'NONE';
          break;
        case 'model2':
          modelSettings.scale = 1.0;
          modelSettings.minimumPixelSize = 64;
          modelSettings.maximumScale = 10000;
          modelSettings.colorEnabled = true;
          modelSettings.color = {
            red: 1.0,
            green: 0.0,
            blue: 0.0,
            alpha: 0.8
          };
          modelSettings.colorBlendMode = 'MIX';
          modelSettings.colorBlendAmount = 0.5;
          break;
        case 'model3':
          modelSettings.scale = 2.0;
          modelSettings.minimumPixelSize = 32;
          modelSettings.maximumScale = 50000;
          modelSettings.colorEnabled = false;
          modelSettings.colorBlendMode = 'NONE';
          break;
      }
      updateModelProperties();
    };

    return {
      selectedModel,
      modelSettings,
      Math,
      onViewerReady,
      updateModelProperties,
      resetToDefaults
    };
  }
};
</script>

<style scoped>
.demo-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.control-panel {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 300px;
  max-height: calc(100% - 40px);
  background: rgba(40, 40, 40, 0.8);
  color: white;
  padding: 15px;
  border-radius: 5px;
  overflow-y: auto;
  z-index: 100;
  backdrop-filter: blur(5px);
}

.control-group {
  margin-bottom: 20px;
}

.control-group h4 {
  margin-top: 0;
  margin-bottom: 10px;
  border-bottom: 1px solid #666;
  padding-bottom: 5px;
}

.reset-button {
  width: 100%;
  padding: 10px;
  background: #2196f3;
  color: white;
  border: none;
  border-radius: 3px;
  cursor: pointer;
  font-weight: bold;
}

.reset-button:hover {
  background: #1976d2;
}
</style>